#ifndef CVIMAGEGRAPH_H
#define CVIMAGEGRAPH_H
#include "Neighbors.h"
//#include <limits>

//const double infinty= numeric_limits<double>::max();
enum Node
{
	source=0,sink
};

class CvImageGraph
{
	public:
		CvImageGraph(CvGraph *graph,uint w,uint h);
		virtual ~CvImageGraph();
		uint NEdges();//* return the number of edges in the graph
		uint NVts();//* return the number of vertices in the graph
		uint VertexIndex(Node n);//* return the index of the source or the sink
		uint VertexIndex(uint x,uint y);//* return the index of (x,y) pixel node
		uint IndexPx(uint index);//* return the x coordinate of the pixel node
		uint IndexPy(uint index);//* return the y coordinate of the pixel node
		uint VertexIndex(CvGraphVtx* vtx);//* return the index of a vertex by a given vertex pointer
		uint EdgeIndex(CvGraphEdge* edge);//* return the index of an edge by a given edge pointer
		uint EdgeIndex(uint IndexA,uint IndexB);//* return the index of an edge by two connected vertices. if they are not connected it returns NULL
		CvGraphEdge* Edge(uint EdgeIdx);//* return the pointer of an edge by its index
		CvGraphEdge* Edge(uint IndexA,uint IndexB);//* return the pointer of an edge by two connected vertices. if they are not connected it returns NULL
		double EdgeWeight(CvGraphEdge *edge);
		double EdgeWeight(uint IndexA,uint IndexB);
		void Connect(uint IndexA,uint IndexB,double weight);
		uint AddVtx();
		void BuildBasicGraph();
		vector<CvGraphEdge*> VertexEdges(CvGraphVtx* vtx);
		vector<CvGraphEdge*> VertexEdges(uint Index);//* all edges who starts or ends at vtx
		vector<CvGraphEdge*> NextEdges(uint Index);//* the same as VertexEdges without the source edges
		vector<uint> NextVts(uint Index);
		double SumWeights(uint VIndex);
		void push_excess(vector<double> & excess,vector<double> & flow,uint u,uint v);
		void max_flow_push(vector<double> & excess,vector<double> & flow,uint u,uint v);
		void max_flow_relabel(vector<uint> & height,vector<double> & flow,uint u);
		void max_flow_discharge(vector<uint> & height,vector<double> & excess,vector<uint> & seen,vector<double> & flow,uint u);
		vector<double> max_flow();
		void GenerateLabelling(CVImage *labelling,vector<double> flow,int label);//* updates the labelling by the graph
		void Clear();


		CvGraph *_graph;
	protected:
	private:
		uint n_vtxs;
		vector<CvGraphEdge*> edges;
		uint height,width;
};

#endif // CVIMAGEGRAPH_H
